using System;
using XLua;

namespace Tutorial
{
	[LuaCallCSharp(GenFlag.No)]
	public class DerivedClass : BaseClass
	{
		[LuaCallCSharp(GenFlag.No)]
		public enum TestEnumInner
		{
			E3,
			E4
		}

		private class InnerCalc : ICalc
		{
			public int id = 100;

			public int add(int a, int b)
			{
				return a + b;
			}
		}

		public Action<string> TestDelegate = delegate(string param)
		{
			DebugUtils.Log(DebugType.Other, "TestDelegate in c#:" + param);
		};

		public int DMF
		{
			get;
			set;
		}

		public event Action TestEvent;

		public void DMFunc()
		{
			DebugUtils.Log(DebugType.Other, "Derived Member Func, DMF = " + DMF);
		}

		public double ComplexFunc(Param1 p1, ref int p2, out string p3, Action luafunc, out Action csfunc)
		{
			DebugUtils.Log(DebugType.Other, "P1 = {x=" + p1.x + ",y=" + p1.y + "},p2 = " + p2);
			luafunc();
			p2 *= p1.x;
			p3 = "hello " + p1.y;
			csfunc = delegate
			{
				DebugUtils.Log(DebugType.Other, "csharp callback invoked!");
			};
			return 1.23;
		}

		public void TestFunc(int i)
		{
			DebugUtils.Log(DebugType.Other, "TestFunc(int i)");
		}

		public void TestFunc(string i)
		{
			DebugUtils.Log(DebugType.Other, "TestFunc(string i)");
		}

		public static DerivedClass operator +(DerivedClass a, DerivedClass b)
		{
			return new DerivedClass
			{
				DMF = a.DMF + b.DMF
			};
		}

		public void DefaultValueFunc(int a = 100, string b = "cccc", string c = null)
		{
			DebugUtils.Log(DebugType.Other, "DefaultValueFunc: a=" + a + ",b=" + b + ",c=" + c);
		}

		public void VariableParamsFunc(int a, params string[] strs)
		{
			DebugUtils.Log(DebugType.Other, "VariableParamsFunc: a =" + a);
			foreach (string str in strs)
			{
				DebugUtils.Log(DebugType.Other, "str:" + str);
			}
		}

		public TestEnum EnumTestFunc(TestEnum e)
		{
			DebugUtils.Log(DebugType.Other, "EnumTestFunc: e=" + e);
			return TestEnum.E2;
		}

		public void CallEvent()
		{
			this.TestEvent();
		}

		public ulong TestLong(long n)
		{
			return (ulong)(n + 1);
		}

		public ICalc GetCalc()
		{
			return new InnerCalc();
		}

		public void GenericMethod<T>()
		{
			DebugUtils.Log(DebugType.Other, "GenericMethod<" + typeof(T) + ">");
		}
	}
}
